package com.slicktechnologies.shared;

import static com.googlecode.objectify.ObjectifyService.ofy;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import com.google.gwt.core.shared.GwtIncompatible;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Index;
import com.googlecode.objectify.annotation.OnLoad;
import com.googlecode.objectify.annotation.OnSave;
import com.googlecode.objectify.annotation.Serialize;
import com.simplesoftwares.client.library.appstructure.search.Filter;
import com.simplesoftwares.client.library.appstructure.search.MyQuerry;
import com.simplesoftwares.client.library.helperconstants.FormTypes;
import com.simplesoftwares.client.library.libservice.GenricService;
import com.simplesoftwares.rebind.annatonations.TableAnnotation;
import com.slicktechnologies.client.config.configurations.ConfigTypes;
import com.slicktechnologies.server.ContractServiceImplementor;
import com.slicktechnologies.server.GenricServiceImpl;
import com.slicktechnologies.server.QuotationServiceImplentor;
import com.slicktechnologies.shared.MyUtility;
import com.slicktechnologies.shared.common.RecievableGoods;
import com.slicktechnologies.shared.common.businessprocesslayer.ConcreteBusinessProcess;
import com.slicktechnologies.shared.common.businessprocesslayer.Customer;
import com.slicktechnologies.shared.common.helperlayer.Address;
import com.slicktechnologies.shared.common.helperlayer.Config;
import com.slicktechnologies.shared.common.helperlayer.PersonInfo;
import com.slicktechnologies.shared.common.paymentlayer.Payment;
import com.slicktechnologies.shared.common.productlayer.ServiceProduct;


/**
 * Represents Contract for approved quotation/s of AMC only.
 */

@Entity
public class Contract extends Quotation implements Serializable
{
	
	public static String CREATED="CREATED";
	public static String DIAGNOSED="DIAGNOSED";
	public static String SUCESSFUL="SUCESSFUL";
	public static String UNSUCESSFUL="UNSUCESSFUL";
	public static String CLOSED="CLOSED";
	
	/************************************************** Attributes**********************************************/
	/** The Constant serialVersionUID. */
	private static final long serialVersionUID = -2219476895484431841L;

	/** advance paid by customer. Zero for non approved Contracts. Uneditable field */
	protected double advance;

	/** balance of this contract. Uneditable field*/
	@Index 
	protected double balance;

	/** payment corresponding to this contract. */
	@Serialize
	protected ArrayList<Payment> payments;

	/** ID of old contract, if this contract is renewed from old contract.Otherwise zero */
	protected int refNo;
	
	protected boolean contractStatusChanged=false;
	
	protected double diagnosisAmount;
	
	@Index
	protected String serviceType;
	@Serialize
	protected ArrayList<RecievableGoods>customerItems;
	
	protected Key<ServiceType>serviceTypeKey;

	/**************************************************Default Constructor*****************************************************/

	/**
	 * Instantiates a new contract.
	 */
	public Contract() 
	{
		super();
		payments=new ArrayList<Payment>();
		contractStatusChanged=false;
		serviceType="";
        customerItems=new ArrayList<RecievableGoods>();
        serviceTypeKey=null;

	}

	/**************************************************Getter/Setter***********************************************************/
	/**
	 * Gets the ref no.
	 * @return the ref no
	 */
	public Integer getRefNo() 
	{
		return refNo;
	}

	/**
	 * Sets the ref no.
	 * @param refNo the new ref no
	 */
	public void setRefNo(Integer refNo)
	{
		this.refNo = refNo;
	}


	/**
	 * Gets the advance.
	 * @return the advance
	 */
	public double getadvance() 
	{
		return this.advance;
	}

	/**
	 * Sets the advance.
	 * @param advance the new advance
	 */
	public void setadvance(Double advance)
	{
		if(advance!=null)
		  this.advance=advance;

	}
	
	

	public List<Payment> getPayments() {
		return payments;
	}

	public void setPayments(List<Payment> payments)
	{
		if(payments!=null)
		{
			this.payments=new ArrayList<Payment>();
			this.payments.addAll(payments);
			System.out.println("Size of Payment"+this.payments.size());
		}
	}

	/**
	 * Gets the balance.
	 * @return the balance
	 */
	//@SearchAnnotation(Datatype = ColumnDatatype.CHECKBOX, flexFormNumber = "12", title = "Balance", variableName = "lbBalance")
	@TableAnnotation(ColType = FormTypes.NUMBERTEXTCELL, colNo = 11, isFieldUpdater = false, isSortable = true, title = "Balance")
	public double getbalance()
	{
		return balance;
	}

	/**
	 * Sets the balance.
	 * @param balance the new balance
	 */
	public void setbalance(Double balance)
	{
		if(balance!=null)
		  this.balance=balance;
	}
	
	
	
	public List<RecievableGoods> getCustomerItems() {
		return customerItems;
	}

	public void setCustomerItems(List<RecievableGoods> configArray) {
		  if(configArray!=null)
		  {
		      this.customerItems = new ArrayList<RecievableGoods>();
		      customerItems.addAll(configArray);
		
		  }
	}

	/**************************************************Relation Management Part****************************************************/
	
	
	
   
	
	
	   
 


	public static List<String> getStatusList()
	{
		ArrayList<String> statuslist=new ArrayList<String>();
		statuslist.add(CREATED);
		statuslist.add(DIAGNOSED);
		statuslist.add(SUCESSFUL);
		statuslist.add(UNSUCESSFUL);
		statuslist.add(CLOSED);
		
		
		return statuslist;
	}


	@GwtIncompatible
	@Override
	public void reactOnApproval() {
		ContractServiceImplementor implementor=new ContractServiceImplementor();
		implementor.changeStatus(this);
	}
	
	
	

	public double getDiagnosisAmount() {
		return diagnosisAmount;
	}

	public void setDiagnosisAmount(double diagnosisAmount) {
		this.diagnosisAmount = diagnosisAmount;
	}

	public String getServiceType() {
		return serviceType;
	}

	public void setServiceType(String serviceType) {
		if(serviceType!=null)
		    this.serviceType = serviceType.trim();
	}
	
	
	
	
	public Key<ServiceType> getServiceTypeKey() {
		return serviceTypeKey;
	}

	public void setServiceTypeKey(Key<ServiceType> serviceTypeKey) {
		this.serviceTypeKey = serviceTypeKey;
	}

	@GwtIncompatible
	@OnSave
	public void maintainRelation()
	{
		
		if(serviceType!=null)
		{
		  serviceTypeKey=ofy().load().type(ServiceType.class).filter("serviceType",getServiceType()).keys().first().now();
		  
		}
		
		
	}
	
	
	@GwtIncompatible
	@OnLoad
	public void loadServiceType()
	{
		
		if(serviceTypeKey!=null)
		{
		  serviceType=ofy().load().key(serviceTypeKey).now().getTypeName();
		  
		}
		
		
	}
	
	
	
}

